package com.matrix.nickel.mqttserver;

import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.core.server.MqttServer;
import org.dromara.mica.mqtt.core.server.dispatcher.IMqttMessageDispatcher;
import org.dromara.mica.mqtt.core.server.event.IMqttConnectStatusListener;
import org.dromara.mica.mqtt.core.server.model.Message;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.tio.core.ChannelContext;

import java.nio.charset.StandardCharsets;

/**
 * @author Nickel
 * @since 2025-02-14 19:57:31
 */
// @Configuration
@Slf4j
public class MqttServerConfiguration {

    @Bean
    public MqttServer mqttServer() {
        // 注意：为了能接受更多链接（降低内存），请添加 jvm 参数 -Xss129k
        MqttServer mqttServer = MqttServer.create()
                // 服务端 ip 默认为空，0.0.0.0，建议不要设置
                .ip("0.0.0.0")
                // 默认：1883
                .port(1883)
                // 默认为： 8092（mqtt 默认最大消息大小），为了降低内存可以减小小此参数，如果消息过大 t-io 会尝试解析多次（建议根据实际业务情况而定）
                .readBufferSize(512)
                // 最大包体长度，如果包体过大需要设置此参数，默认为： 8092
                .maxBytesInMessage(1024 * 100)
                // 自定义认证
                .authHandler((context, uniqueId, clientId, userName, password) -> true)
                // 消息监听
                .messageListener((context, clientId, topic,qoS, message) -> {
                    log.info("clientId:{} message:{} payload:{}", clientId, message, new String(message.getPayload(), StandardCharsets.UTF_8));
                })
                // 心跳超时时间，默认：120s
                .heartbeatTimeout(120_1000L)
                // 开启代理协议，支持 nginx 开启 tcp proxy_protocol on; 时转发源 ip 信息。2.4.1 版本开始支持
                .proxyProtocolEnable()
                // 自定义客户端上下线监听
                .connectStatusListener(new IMqttConnectStatusListener() {
                    @Override
                    public void online(ChannelContext context, String clientId, String username) {
                        log.info("{} has is online...., username: {}", clientId, username);
                    }

                    @Override
                    public void offline(ChannelContext context, String clientId, String username, String reason) {
                        log.info("{} is offline....username: {}, reason: {}", clientId, username, reason);
                    }
                })
                // 自定义消息转发，可用 mq 广播实现集群化处理
                .messageDispatcher(new IMqttMessageDispatcher() {

                    @Override
                    public boolean send(Message message) {
                        return false;
                    }

                    @Override
                    public boolean send(String clientId, Message message) {
                        return false;
                    }
                })
                .httpEnable(false)
                .websocketEnable(false)
                .debug() // 开启 debug 信息日志
                .start();

        // mqttServer.publish("clientId", "/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8));

        // mqttServer.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8));

        return mqttServer;
    }
}
